package cn.remex.db;

import cn.remex.db.rsql.connection.RDBManager;
import cn.remex.db.rsql.model.Modelable;
import cn.remex.db.utils.StringHelper;
import cn.remex.db.utils.spring.SpringContextUtil;

import static cn.remex.db.rsql.RsqlConstants.DS_needSave;
import static cn.remex.db.rsql.connection.RDBManager.DEFAULT_SPACE;


/**
 * 2016-05-01 LHY 重构
 * <p>
 * 本方法为数据操作的入口工厂方法<br>
 * <p>
 * Remex2 框架中数据由两部分构成<br>
 * 1.管理连接和事务的{@link RDBManager}<br>
 * 2.管理SQL和ORM的{@link Container}<br>
 */
public class Database {

    public static Container getSession() {
        return getSession(DEFAULT_SPACE);
    }

    public static Container getSession(String spaceName) {
        Class<? extends Container> containerClass = RDBManager.getLocalSpaceConfig(spaceName).getContainerClass();
        Container container = SpringContextUtil.getBean(containerClass);
        container.setSpaceName(spaceName);
        return container;
    }

    public static <T extends Modelable> DbCvo<T, ?> createDbCvo(Class<T> beanClass) {
        return createDbCvo(beanClass, DEFAULT_SPACE);
    }

    public static <T extends Modelable> DbCvo<T, ?> createDbCvo(Class<T> beanClass, String spaceName) {
        return getSession(spaceName).createDbCvo(beanClass);
    }

    public static Container space(String spaceName) {
        return getSession(spaceName);
    }

    public static <T extends Modelable> DbCvo<T, ?> select(Class<T> beanClass, String spaceName) {
        return space(spaceName).createDbCvo(beanClass).executeMethod("Select");
    }

    public static <T extends Modelable> DbCvo<T, ?> update(Class<T> beanClass, String spaceName) {
        return space(spaceName).createDbCvo(beanClass).executeMethod("Update");
    }

    public static <T extends Modelable> DbCvo<T, ?> delete(Class<T> beanClass, String spaceName) {
        return space(spaceName).createDbCvo(beanClass).executeMethod("Delete");
    }

    public static <T extends Modelable> DbCvo<T, ?> insert(Class<T> beanClass, String spaceName) {
        return space(spaceName).createDbCvo(beanClass).executeMethod("Insert");
    }

    public static <T extends Modelable> DbCvo<T, ?> store(Class<T> beanClass, String spaceName) {
        return space(spaceName).createDbCvo(beanClass).executeMethod("Store");
    }

    public static <T extends Modelable> DbCvo<T, ?> insert(T model, String spaceName) {
        Container curSpace = space(spaceName);
        Class<T> modelClass = curSpace.obtainModelClass(StringHelper.getClassSimpleName(model.getClass()));
        return curSpace.createDbCvo(modelClass).executeMethod("Insert").assignBean(model);
    }

    public static <T extends Modelable> DbCvo<T, ?> store(T model, String spaceName) {
        model._setDataStatus(DS_needSave);
        Container curSpace = space(spaceName);
        Class<T> modelClass = curSpace.obtainModelClass(StringHelper.getClassSimpleName(model.getClass()));
        return curSpace.createDbCvo(modelClass).executeMethod("Store").assignBean(model);
    }


    public static <T extends Modelable> DbCvo<T, ?> select(Class<T> beanClass) {
        return select(beanClass, DEFAULT_SPACE);
    }

    public static <T extends Modelable> DbCvo<T, ?> update(Class<T> beanClass) {
        return update(beanClass, DEFAULT_SPACE);
    }

    public static <T extends Modelable> DbCvo<T, ?> delete(Class<T> beanClass) {
        return delete(beanClass, DEFAULT_SPACE);
    }

    public static <T extends Modelable> DbCvo<T, ?> insert(Class<T> beanClass) {
        return insert(beanClass, DEFAULT_SPACE);
    }

    public static <T extends Modelable> DbCvo<T, ?> store(Class<T> beanClass) {
        return store(beanClass, DEFAULT_SPACE);
    }

    public static <T extends Modelable> DbCvo<T, ?> insert(T model) {
        return store(model, DEFAULT_SPACE);
    }

    public static <T extends Modelable> DbCvo<T, ?> store(T model) {
        return store(model, DEFAULT_SPACE);
    }

}